print("hax loaded");
class RconClients
{
	iID = false;
	Name = null;
	LoggedIn = false;
	Session = null;
	szChat = {};
}
function RconStart( iPort )
{
	RconSocket <- NewSocket( "RconProcess" );
	RconSocket.SetNewConnFunc( "RconNewConn" );
	RconSocket.Start( iPort, 40 );
	Clients <- array( 40, null );
	print("Starting Rcon Server on Port " + iPort );
	print("LU Rcon Server v1.0 by [VU]Thijn");
}
function RconProcess( iSocket, iID, szData )
{
	local cmd = GetTok( szData, " ", 1 );
	local Username = ReadIniString( "Sessions.ini", "SESSIONS", cmd );
	if ( Username != "" )
	{
		local cmd = GetTok( szData, " ", 2 );
		if ( cmd == "GETCHAT" )
		{
			local SesID = FindSessionClass( GetTok( szData, " ", 1 ) );
			if ( Clients[ SesID ].szChat.len() > 0 )
			{
				iSocket.SendClient( Clients[ SesID ].szChat.len().tochar(), iID );
				foreach( msg in Clients[ SesID ].szChat )
				{
					iSocket.SendClient( msg.len().tochar() + msg, iID );
				}
				Clients[ SesID ].szChat = {};
			} 
			else iSocket.SendClient( "0", iID );
		}
		else if ( cmd == "GETPORT" )
		{
			iSocket.SendClient( GetPort().tostring(), iID );
		}
		else if ( cmd == "GETPLAYER" )
		{
			print( "Player Info: " + szData );
			local plr = FindPlayer( GetTok( szData, " ", 3 ).tointeger() );
			if ( plr )
			{
				local msg = plr.Name + "\x0003" + plr.IP + "\x0003" + plr.Health + "\x0003" + plr.Armour;
				iSocket.SendClient( msg.len().tochar() + msg, iID );
			}
			else iSocket.SendClient( "0", iID );
		}
		else if ( cmd == "SAY" )
		{
			local len = GetTok( szData, " ", 1 ).len() + GetTok( szData, " ", 2 ).len() + 2;
			local msg = szData.slice( len );
			Message( "[#FF0000][Rcon][#d] " + Username + ": " + msg );
			EchoMessage( "4[RCON] " + Username + ": " + msg );
			RconChat("<font color=\"#FF0000\">[RCON]</font> " + Username + ": " + msg );
		}
		else if ( cmd == "LOGOUT" )
		{
			RemoveIniValue( "Sessions.ini", "SESSIONS", GetTok( szData, " ", 1 ) );
			RconChat("<font color=\"#FF0000\">[RCON]</font> " + Username + " logged out.");
			Message( "[#FF0000][Rcon][#d] " + Username + " logged out." );
			EchoMessage( "4[RCON] " + Username + " logged out." );
			RconChat("<font color=\"#FF0000\">[RCON]</font> " + Username + " logged out." );
		}
		else if ( cmd == "KICK" )
		{
			local plr = FindPlayer( GetTok( szData, " ", 3 ).tointeger() );
			if ( plr )
			{
				local len = GetTok( szData, " ", 1 ).len() + GetTok( szData, " ", 2 ).len() + GetTok( szData, " ", 3 ).len() + 3;
				local msg = szData.slice( len );
				EMessage("[RCON] Admin " + Username + " kicked " + plr.Name + " [ Reason: " + msg + " ]", Col_Blue);
				RconChat("<font color=\"#FF0000\">[RCON]</font><font color=\"#0000FF\"> Admin " + Username + " kicked " + plr.Name + " [ Reason: " + msg + " ]</font>");
				onPlayerPart( plr, PARTREASON_KICKED );
				KickPlayer( plr );
			}
		}
		else if ( cmd == "BAN" )
		{
			local plr = FindPlayer( GetTok( szData, " ", 3 ).tointeger() );
			if ( plr )
			{
				local len = GetTok( szData, " ", 1 ).len() + GetTok( szData, " ", 2 ).len() + GetTok( szData, " ", 3 ).len() + 3;
				local msg = szData.slice( len );
				EMessage("[RCON] Admin " + Username + " banned " + plr.Name + " [ Reason: " + msg + " ]", Col_Blue);
				RconChat("<font color=\"#FF0000\">[RCON]</font><font color=\"#0000FF\"> Admin " + Username + " banned " + plr.Name + " [ Reason: " + msg + " ]</font>");
				MessagePlayer("You were banned by " + Username + " for " + msg + "! Appeal at http://gamesparks.windlord.net", plr, Col_Orange );
				BanListAdd( plr, Username, msg, BanType.PermBan );
				onPlayerPart( plr, PARTREASON_BANNED );
				BanPlayer( plr );
			}
		}
		else if ( cmd == "UNBAN" )
		{
			local IP = GetTok( szData, " ", 3 );
			EMessage("[RCON] Admin " + Username + " unbanned IP:[ " + GetTok( szData, " ", 3 ) + " ]", Col_Blue);
			RconChat("<font color=\"#FF0000\">[RCON]</font><font color=\"#0000FF\"> Admin " + Username + " unbanned IP:[ " + GetTok( szData, " ", 3 ) + " ]</font>");
			BanListUnban( IP );
			UnbanIP( IP );
		}
	}
	else if ( cmd == "AUTH" )
	{
		local UserName = ReadIniString( "Admins.ini", "ADMINS", GetTok( szData, " ", 2 ) );
		if ( UserName )
		{
			if ( UserName == GetTok( szData, " ", 3 ) )
			{
				local szSession = SHA1( RandNum ( 0, 1000).tostring() );
				WriteIniString( "Sessions.ini", "SESSIONS", szSession , GetTok( szData, " ", 2 ) );
				local ClassID = FindEmptyClass();
				Clients[ ClassID ] = RconClients();
				Clients[ ClassID ].iID = iID;
				Clients[ ClassID ].Name = GetTok( szData, " ", 2 );
				Clients[ ClassID ].LoggedIn = true;
				Clients[ ClassID ].Session = szSession;
				iSocket.SendClient( "1LOGGEDIN " + szSession, iID );
				Message( "[#FF0000][Rcon][#d] " + GetTok( szData, " ", 2 ) + " logged in." );
				EchoMessage( "4[RCON] " + GetTok( szData, " ", 2 ) + " logged in." );
				RconChat( "<font color=\"#FF0000\">[RCON]</font> " + GetTok( szData, " ", 2 ) + " logged in." );
			}
			else iSocket.SendClient( "0", iID );
		}
		else iSocket.SendClient( "0", iID );
	}
	else iSocket.SendClient( "0", iID );
}

function RandNum ( start, end = 0 )
{
        if ( !end ) { end = start; start = 1; }
        return start + ( rand() % ( end - start + 1 ) );
}
function FindEmptyClass()
{
	for( local i = 0; i < 40; i++ )
	{
		if ( typeof( Clients[ i ] ) != "instance" )
		{
			return i;
		}
	}
}
function FindSessionClass( szSession )
{
	for( local i = 0; i < 40; i++ )
	{
		if ( typeof( Clients[ i ] ) == "instance" )
		{
			if ( Clients[ i ].Session == szSession )
			{
				return i;
			}
		}
	}
}
function RconChat( szMessage )
{
	local dt = date();
	local DateStamp = "<<<small>" + dt.hour + ":" + dt.min + ":" + dt.sec + "</small>>> ";
	for( local i = 0; i < 40; i++ )
	{
		try {
		if ( typeof( Clients[ i ] ) == "instance" )
		{
			if ( Clients[ i ].Session )
			{
				Clients[ i ].szChat.rawset( Clients[ i ].szChat.len(), DateStamp + szMessage );
		    }
		}
		}
		catch(e) { }
	}
}
function RcononPlayerAction( pPlayer, szMessage ) RconChat( "<font color=\"#FC7F00\">** " + pPlayer.Name + " " + szMessage + "</font>" );
function RcononPlayerJoin( pPlayer ) RconChat( "<font color=\"#009300\">** [" + pPlayer.ID + "] " + pPlayer.Name + " has joined the server.</font>" );
function RcononPlayerChat( pPlayer, szMessage ) RconChat( "<font color=\"#FC7F00\">[" + pPlayer.ID + "]</font><font color=\"#0000FC\"> " + pPlayer.Name + ": </font><font color=\"#000000\">" + szMessage + "</font>" );
function RcononPlayerCommand( pPlayer, szCommand, szArgs ) RconChat( "<font color=\"#FC7F00\">[" + pPlayer.ID + "]</font><font color=\"#0000FC\"> " + pPlayer.Name + ":</font><font color=\"#000000\"> /" + szCommand + ( szArgs != null ? " " + szArgs : "" ) + "</font>" );
function RcononPlayerDeath( pPlayer, iReason ) RconChat( "<font color=\"#FF0000\">** [" + pPlayer.ID + "] " + pPlayer.Name + " Died.</font>" );
function RcononPlayerKill( killer, player, reason, bodypart ) RconChat( "<font color=\"#FF0000\">* " + killer.Name + " killed " + player.Name " (" + GetWeaponName( reason ) + ")</font>" );
function RcononPlayerPart( pPlayer, iReason ) RconChat( "<font color=\"#009300\">** [" + pPlayer.ID + "] " + pPlayer.Name + " has left the server. ( " + QuitReason( iReason ) + " )</font>" );